package com.kwlt.smc.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.kwlt.smc.dao.CPDao;
import com.kwlt.smc.dao.UserChannelDao;
import com.kwlt.smc.entity.CP;
import com.kwlt.smc.entity.Channel;
import com.kwlt.smc.entity.InterRespInfo;
import com.kwlt.smc.entity.SmsInfo;
import com.kwlt.smc.entity.User;
import com.kwlt.smc.service.IValidationSms;
import com.kwlt.smc.service.JedisService;
import com.kwlt.smc.service.UserService;
import com.kwlt.smc.util.CacheMap;
import com.kwlt.smc.util.ConUtils;
import com.kwlt.smc.util.Constants;
import com.kwlt.smc.util.JedisKey;
import com.kwlt.smc.util.MD5;
import com.kwlt.smc.web.SendSmsController;


@Component
public class VailidationSmsImpl implements IValidationSms {
	
	private static Logger logger = LoggerFactory.getLogger(SendSmsController.class);
	@Autowired
	private UserService userService;
	@Autowired
	private CPDao cpDao;
	@Autowired
	private UserChannelDao userChannelDao;
	@Override
	public void validationSms(SmsInfo smsInfo,InterRespInfo resp) {
			// 1:验证用户名密码
			if(StringUtils.isBlank(smsInfo.getUser()) || StringUtils.isBlank(smsInfo.getPwd())){
				// 1:验证用户名错误
				resp.setRespCode("003");
				resp.setRespDesc("用户名密码验证错误");
				return;
			}
			User u = userService.findUserByLoginNamePassword(smsInfo.getUser(),smsInfo.getPwd());
			if (u == null) {
				// 1:验证用户名错误
				resp.setRespCode("003");
				resp.setRespDesc("用户名密码验证错误");
				return;
			}
			smsInfo.setOuser(u);
			// 2:验证MD5
			if (!validateMD5(smsInfo,u)) {
				resp.setRespCode("004");
				resp.setRespDesc("授权加密验证错误");
				return;
			}
			// 4:验证IP地址
			if (!validateIp(smsInfo.getIp(),u.getIpAddress(),u.getIsIp())) {
				// 4:验证IP地址失败
				resp.setRespCode("001");
				resp.setRespDesc("ip验证错误");
				return;
			}
			//过滤号段
			validatePhoneThemRoughly(smsInfo,u.getProvCode(),u.getIsFilterPhone());	
			// 5 验证手机号码
			if (!validatePhone(smsInfo.getDest())) {
				// 5:验证手机号码失败
				resp.setRespCode("006");
				resp.setRespDesc("手机号错误");
				return;
			}
			//过滤空通道手机号
			if(!valdateChannel(smsInfo)){
				resp.setRespCode("107");
				resp.setRespDesc("未配置通道");
				return;
			}
			if (!validateRepeat(smsInfo)) {
				resp.setRespCode("102");
				resp.setRespDesc("和最近的内容重复（避免短时间内重发）");
				return;
			}
			//签名验证
			if("2".equals(u.getSignatureType())){
				//验证客户签名
				if(!validateSign(smsInfo,u)){
					resp.setRespCode("103");
					resp.setRespDesc("签名验证未通过");
					return;
				}
			}
			//判断预付费用户的余额
			if(u.getUserType()!=null && "Y".equals(u.getUserType())){
				if(!validateBal(smsInfo,u)){
					resp.setRespCode("104");
					resp.setRespDesc("余额不足，请及时充值");
					return;
				}
			}
			//校验号码最小个数
			if(u.getMinPhoneNumbers()!=null && !"".equals(u.getMinPhoneNumbers())){
				if(!validatePhoneNumbers(smsInfo.getDest(),u.getMinPhoneNumbers().intValue(),"min")){
					resp.setRespCode("105");
					resp.setRespDesc("不足号码最小提交个数限制");
					return;
				}
			}
			if(u.getMaxPhoneNumbers()!=null && !"".equals(u.getMaxPhoneNumbers())){
				if(!validatePhoneNumbers(smsInfo.getDest(),u.getMaxPhoneNumbers().intValue(),"max")){
					resp.setRespCode("106");
					resp.setRespDesc("超出号码最大提交个数限制");
					return;
				}
			}
	}
	
	/**
	 * 校验号码个数
	 * @param dest 号码组
	 * @param numbers 限制个数
	 * @param operator 操作符类型判断 "min","max"
	 * @return
	 */
	private boolean validatePhoneNumbers(String dest,int numbers,String operator){
		boolean flag = true;
		if (!StringUtils.isEmpty(dest)) {
			String[] destArray = dest.split(Constants.REXG);
			if("min".equals(operator)){
				//判断最少号码个数限制
				if(destArray.length<numbers){
					flag = false;
				}
			}
			if("max".equals(operator)){
				if(destArray.length>numbers){
					flag = false;
				}
			}
		}else{
			flag = false;
		}
		return flag;
	}
	
	/**
	 * 过滤用户是否配置了三网通道，如果未配置，则过滤提交号码
	 * @param smsInfo
	 * @return
	 */
	private boolean valdateChannel(SmsInfo smsInfo){
		List userChannel = userChannelDao.getUserChannel(smsInfo.getUser());
		Map<String,String> operMap = new HashMap<String,String>();
		if(userChannel!=null && userChannel.size()>0){
			for(int i=0;i<userChannel.size();i++){
				Object[] obj = (Object[]) userChannel.get(i);
				Channel channel = (Channel) obj[0];
				if(channel!=null){
					operMap.put(channel.getOperators(), channel.getOperators());
				}
			}
		}
		String dest = smsInfo.getDest();
		if(operMap.containsKey(Constants.MOBILE)
				&& operMap.containsKey(Constants.UNICOM)
				&& operMap.containsKey(Constants.TELECOM)){
			return true;
		}else{
			//查看哪个运营商通道为空
			for (String phone:dest.split(Constants.REXG)) {
				if(!operMap.containsKey(Constants.MOBILE)){
					if(ConUtils.isMobileNo(phone)){
						removePhone(smsInfo, phone, "", "filter null moblie channel:");
					}
				}
				if(!operMap.containsKey(Constants.UNICOM)){
					if(ConUtils.isUnicomNo(phone)){
						removePhone(smsInfo, phone, "", "filter null unicom channel:");
					}
				}
				if(!operMap.containsKey(Constants.TELECOM)){
					if(ConUtils.isTelecomNo(phone)){
						removePhone(smsInfo, phone, "", "filter null telecom channel:");
					}
				}
			}
		}
		if(StringUtils.isBlank(smsInfo.getDest())){
			return false;
		}else{
			return true;
		}
	}
	
	private boolean validateBal(SmsInfo info,User user){
		JedisService jedis = new JedisService(Constants.REDIS_IP,Constants.REDIS_PASSWORD);
		String[] phone = info.getDest().split(Constants.REXG);
		//查询用户所属企业的序号
		if(user.getCpId()!=null){
			CP cp = cpDao.findOne(user.getCpId());
			if(cp!=null && !StringUtils.isBlank(cp.getCpNumbers())){
				Long count = jedis.saveCount(JedisKey.CP_SEND_NUMBERS_PREFIX+cp.getCpNumbers(), -phone.length);
				if(count<0){
					//证明余额不足,将已扣除的值，返回
					jedis.saveCount(JedisKey.CP_SEND_NUMBERS_PREFIX+cp.getCpNumbers(), phone.length);
					return false;
				}
			}
		}
		return true;
	}
	
	private boolean validateSign(SmsInfo info,User user){
		String msg = info.getMsg();
		if(!StringUtils.isBlank(user.getSignature())){
			for(String sign:user.getSignature().split(",")){
				if(msg.endsWith(sign) || msg.indexOf(sign)==0){
					return true;
				}
			}
		}
		return false;
	}
	
	private boolean validateMD5(SmsInfo info, User user) {
		// 必须授权
		if (user.getIsMd5() != null && "0".equals(user.getIsMd5())) {
			// 进行授权
			String md5 = MD5.MD5Encode(info.getDest() + info.getMsg() + user.getUserAuthCode());
			if (md5.equals(info.getAuthcode())) {
				// 授权验证成功
				return true;
			} else {
				// 授权验证失败
				return false;
			}
		}
		return true;

	}
	
	/**
	 * 过滤号段内容
	 * @param dest 手机号串
	 * @param provCode 省份编码
	 * @param isThemRoughly 是否过滤
	 */
	private void validatePhoneThemRoughly(SmsInfo smsInfo,String provCode,String isThemRoughly){
		Map<String, String> phoneThemRoughlyMap = CacheMap.phoneThemRoughlyMap;
		if("0".equals(isThemRoughly)){
			//需要过滤
			String dest = smsInfo.getDest();
			if(!StringUtils.isBlank(provCode) && !StringUtils.isBlank(dest)){
				List<String> list = new ArrayList<String>();
				String[] provarray = provCode.split(Constants.REXG);
				for(int i=0;i<provarray.length;i++){
					list.add(provarray[i]);
				}
				for (String phone:dest.split(Constants.REXG)) {
					String prov = phoneThemRoughlyMap.get(phone.substring(0, 7));
					if(list.contains(prov)){
						//如果用户过滤省份于缓存中相符，则要过滤掉该手机号
						removePhone(smsInfo, phone,prov,"filter rid:");
					}
				}
			}
		}
	}
	
	private void removePhone(SmsInfo smsInfo, String phoneNumber,String prov,String log) {
		String phone=smsInfo.getDest();
		if(phone.equals(phoneNumber)){
			logger.info(log+prov+"\t"+smsInfo.getUser()+"\t"+phoneNumber+"\t"+smsInfo.getMsg());
			smsInfo.setDest("");
		}else if(phone.startsWith(phoneNumber)){
			smsInfo.setDest(phone.replaceAll(phoneNumber+",", ""));
			removePhone(smsInfo,phoneNumber,prov,log);
		}else{
			logger.info(log+prov+"\t"+smsInfo.getUser()+"\t"+phoneNumber+"\t"+smsInfo.getMsg());
			smsInfo.setDest( phone.replaceAll(","+phoneNumber, ""));
		}
	}
	/**
	 * 
	 * @param ip 客户请求IP
	 * @param userIp 数据库配置IP
	 * @param isIp 是否需要验证
	 * @return
	 */
	private boolean validateIp(String ip, String userIp,String isIp) {
		//不需要验证IP
		if(StringUtils.isBlank(isIp) || !isIp.equals("0")){
			return true;
		}
		String[] userIpArray = userIp.split(Constants.REXG);
		for(int i=0;i<userIpArray.length;i++){
			String ui = userIpArray[i];
			if(ip.equals(ui)){
				return true;
			}
		}
		return false;
	}
	/**
	 * 
	 * @param desc 客户请求手机号码组
	 * @return
	 */
	private boolean validatePhone(String dest) {
		if (!StringUtils.isEmpty(dest)) {
			for (String phone : dest.split(Constants.REXG)) {
				if (!ConUtils.isPhoneNo(phone)) {
					return false;
				}
			}
			return true;
		} else {
			return false;
		}
	}

	private boolean validateRepeat(SmsInfo smsInfo) {
		
		return true;
	}
}
